
#include "StdAfx.h"
#include "DBLibs.h"

#include <StaticProcessInfo.h>

DBStat::DBStat(){
	active_ = false;
}

DBStat::~DBStat(){
}

bool DBStat::initialize( char* name ){
#ifdef WIN32
	data_ = new WinShareMemory< STSharedDBStat >();
#endif
#ifdef LINUX
	data_ = new UnixShareMemory< STSharedDBStat >();
#endif

	std::string strName = name;
	if( strName == "noname" )
		return false;

	strName += "_db";

	int iResult = data_->create( DEF_MAX_STAT_SIZE, strName.c_str() );

	if( iResult == ShareMemory<STSharedDBStat>::DEF_SHM_CREATE_FAIL ){
		LOG_ERR( LOG_SERVICE( "instance" )->Log("fail db_stat shared memory = %s", strName.c_str() ) );
		return false;
	}

	if( iResult == ShareMemory<STSharedDBStat>::DEF_SHM_CREATE_ALREADY ){
		LOG_INSTANCE( LOG_SERVICE( "instance" )->Log("already exist db_stat shared memory = %s", strName.c_str() ) );
		return true;
	}
	
	STSharedDBStat* pData = 0;
	for( size_t i = 0; i < DEF_MAX_STAT_SIZE; i++ ){
		pData = data_->get( i );

		if(! pData )
			continue;

		memset( pData, 0, sizeof( STSharedDBStat ) );
	}

	LOG_INSTANCE( LOG_SERVICE( "instance" )->Log("create db_stat shared memory = %s", strName.c_str() ) );
	
	active_ = true;

	StaticProcessInfo::Instance()->register_shared_name( (char*)data_->getName(), StaticProcessInfo::DEF_SHARED_MEMORY_TYPE_DB );

	return true;
}

int DBStat::set( char* session_name, size_t free_count, size_t busy_count ){
	if(! active_ )
		return DEFAULT_FAIL;

	IS_NULL_RETURN( session_name, DEFAULT_FAIL );	
	
	if(! strlen( session_name ) )
		return DEFAULT_FAIL;
	
	STSharedDBStat* pData = get( session_name );
	size_t i = 0;
	if(! pData ){
		for( i = 0; i < DEF_MAX_STAT_SIZE; i++ ){
			pData = data_->get( i );

			IS_NULL_ACTION( pData, continue );

			if( strlen(pData->name) )
				continue;

			strncpy( pData->name, session_name, strlen( session_name ) );
			pData->free_instance_count = 0;
			pData->busy_instance_count = 0;

			break;
		}

		if( i >= DEF_MAX_STAT_SIZE )
			return DEFAULT_FAIL;
	}

	pData->free_instance_count = free_count;
	pData->busy_instance_count = busy_count;	
	pData->main_loop++;

	return DEFAULT_SUCCESS;
}

DBStat::STSharedDBStat* DBStat::get( char* session_name ) const{
	if(! active_ )
		return 0;

	IS_NULL_RETURN( session_name, 0 );	

	if(! strlen( session_name ) )
		return 0;

	STSharedDBStat* pData = 0;
	for( size_t i = 0; i < DEF_MAX_STAT_SIZE; i++ ){
		pData = data_->get( i );

		IS_NULL_ACTION( pData, continue );		

		if(! strlen(pData->name) )
			continue;

		if(! strncmp( pData->name, session_name, strlen( session_name ) ) )
			return pData;
	}

	return 0;
}

DBAccount::DBAccount(){
}

DBAccount::DBAccount( DBAccount& account ){
	name_ = account.name_;
	address_ = account.address_;
	id_ = account.id_;
	passwd_ = account.passwd_;
	port_ = account.port_;

	if( account.option_.size() )
		option_ = account.option_;

	if( account.db_.size() )
		db_ = account.db_;
}

DBAccount::~DBAccount(){	
}

void DBAccount::set( const char* name, const char* address, const char* id, \
		const char* passwd, const size_t port, const char* db, const char* option )
{	
	name_ = name;
	address_ = address;
	id_ = id;
	passwd_ = passwd;
	port_ = port;	

	if( option )
		option_ = option;

	if( db )
		db_ = db;
}

void DBAccount::setPort( int port ){
	port_ = port;
}

const char* DBAccount::getName(){
	return name_.c_str();
}

const char* DBAccount::getAddress(){	
	return address_.c_str();	
}

const char* DBAccount::getID(){
	return id_.c_str();
}

const char* DBAccount::getPasswd(){
	return passwd_.c_str();
}

const size_t DBAccount::getPort(){
	return port_;
}

const char* DBAccount::getOption(){
	if(! option_.size() )
		return 0;

	return option_.c_str();
}

const char* DBAccount::getDBName(){
	if(! db_.size() )
		return 0;

	return db_.c_str();
}

DBTableDescription::DBTableDescription(){
}

DBTableDescription::~DBTableDescription(){		
	reset();
}

void DBTableDescription::reset(){
	m_attribute_.clear();
}

size_t DBTableDescription::getColumnCount(){
	return m_attribute_.size();
}

void DBTableDescription::addColumnInfo(char* column_name, short type, char* type_name, \
		int size, int buffer_length, short decimal_digits, short numPrec_radix, \
		short nullable, char* remarks, char* column_default, short sqlData_type, \
		short datetime_subtypeCode, int charOctet_length, int ordinal_position, \
		char* isNullable)
{
	TableAttribute attr;
	attr.type = type;
	attr.buffer_length = buffer_length;
	attr.charOctet_length = charOctet_length;

	if( column_default )
		strncpy( attr.column_default, column_default, 129 );

	if( column_name )
		strncpy( attr.column_name, column_name, 129 );

	attr.datetime_subtypeCode = datetime_subtypeCode;
	attr.decimal_digits = decimal_digits;

	if( isNullable )
		strncpy( attr.isNullable, isNullable, 129 );

	attr.nullable = nullable;
	attr.numPrec_radix = numPrec_radix;
	attr.ordinal_position = ordinal_position;

	if( remarks )
		strncpy(attr.remarks, remarks, 255);

	attr.size = size;
	attr.sqlData_type = sqlData_type;	

	if( type_name )
		strncpy( attr.type_name, type_name, 129 );
	
	m_attribute_.push_back(attr);
}

char* DBTableDescription::getColumnName(size_t idx){
	if( m_attribute_.size() <= idx )
		return 0;
	
	return m_attribute_[idx].column_name;
}

short DBTableDescription::getColumnType(size_t idx){
	if( m_attribute_.size() <= idx )
		return -1;
	
	return m_attribute_[idx].type;
}

char* DBTableDescription::getColumnTypeName(size_t idx){
	if( m_attribute_.size() <= idx )
		return 0;
	
	return m_attribute_[idx].type_name;
}

int DBTableDescription::getColumnSize(size_t idx){
	if( m_attribute_.size() <= idx )
		return -1;
	
	return m_attribute_[idx].size;
}

short DBTableDescription::getColumnNullable(size_t idx){
	if( m_attribute_.size() <= idx )
		return -1;
	
	return m_attribute_[idx].nullable;
}

int DBTableDescription::getColumnBufferSize(size_t idx){
	if( m_attribute_.size() <= idx )
		return -1;
	
	return m_attribute_[idx].buffer_length;
}

void DBTableDescription::setColumnBufferSize( int idx, int size ){
	if( m_attribute_.size() <= idx )
		return;
	
	m_attribute_[idx].buffer_length = size;
}

short DBTableDescription::getColumnType(char* szName){
	TableAttribute* pValue = getTableAttribute( szName );

	if( pValue )
		return pValue->type;

	return 0;
}

char* DBTableDescription::getColumnTypeName(char* szName){
	TableAttribute* pValue = getTableAttribute(szName);

	if( pValue )
		return pValue->type_name;
	return 0;
}

int DBTableDescription::getColumnSize(char* szName){
	TableAttribute* pValue = getTableAttribute(szName);

	if( pValue )
		return pValue->size;
	return -1;
}

short DBTableDescription::getColumnNullable(char* szName){
	TableAttribute* pValue = getTableAttribute(szName);

	if( pValue )
		return pValue->nullable;
	return -1;
}

int DBTableDescription::getColumnBufferSize(char* szName){
	TableAttribute* pValue = getTableAttribute(szName);

	if( pValue )
		return pValue->buffer_length;
	return -1;
}

DBTableDescription::TableAttribute* DBTableDescription::getTableAttribute(char* szName){
	TableAttribute* pRetValue = 0;
	StringObj strName(szName);

	for( size_t i = 0 ; i < m_attribute_.size() ; i++ ){
		pRetValue = &(m_attribute_[i]);
		if( strName.isEqualIgnLetterType( pRetValue->column_name ) )
			return pRetValue;
	}

	return 0;
}

void DBTableDescription::setName(char* name){
	m_name_ = name;
}

const char* DBTableDescription::getName(){
	return m_name_.c_str();
}
